﻿using System;
using System.Collections.Generic;
using System.Linq;

using RayDen.Library.Core.Primitives;

namespace RayDen.Library.Core.Collections {

    public class FloatStore : List<float> {
        public FloatStore():base() {}
        public FloatStore(IEnumerable<float> c ):base(c){}
    }
    public class IntStore : List<int> {
        public IntStore() : base() { }

        public IntStore( IEnumerable<int> c ) : base(c) { }
    }

    public static class FloatStoreExtensions {

        public static IEnumerable<Vector> TodVectorList( this FloatStore vc ) {
            for( var i = 0; i < vc.Count; i += 3 ) {
                yield return new Vector() { X = vc[i], Y = vc[i + 1], Z = vc[i + 2] };
            }
        }

        public static IEnumerable<Point> ToPointList( this FloatStore vc )
        {
            for (var i = 0; i < vc.Count; i += 3)
            {
                yield return new Point()
                {
                    X = vc[i],
                    Y = vc[i + 1],
                    Z = vc[i + 2]
                };
            }
        }

        public static IEnumerable<float> ToFloatArray(this IEnumerable<double> arr) {
            return arr.Select(item=>(float)item);
        }

        public static IEnumerable<Vector> ToVectorList(this IList<double> vc) {
            for (var i = 0; i < vc.Count; i += 3) {
                yield return new Vector() { X = (float)vc[i], Y = (float)vc[i + 1], Z = (float)vc[i + 2] };
            }
        }
        public static IEnumerable<Point> ToPointList( this IList<double> vc )
        {
            for (var i = 0; i < vc.Count; i += 3)
            {
                yield return new Point()
                {
                    X = (float)vc[i],
                    Y = (float)vc[i + 1],
                    Z = (float)vc[i + 2]
                };
            }
        }
        public static IEnumerable<Normal> ToNormalList(this IList<double> vc) {
            for (var i = 0; i < vc.Count; i += 3) {
                yield return new Normal() { X = (float)vc[i], Y = (float)vc[i + 1], Z = (float)vc[i + 2] };
            }
        }

        public static IEnumerable<Vector> ToVectorList(this IEnumerable<UV> vc) {
            return vc.Select(uv => new Vector(uv.U, uv.V, 0f));
        }

        public static IEnumerable<Normal> ToNormalList( this FloatStore vc ) {
            for( var i = 0; i < vc.Count; i += 3 ) {
                yield return new Normal() { x = vc[i], y = vc[i + 1], z = vc[i + 2] };
            }
        }

        public static IEnumerable<float> ToFloatList(this IEnumerable<Vector> vc) {
            return vc == null ? new float[0] : vc.SelectMany(item => item.ToArray());
        }

        public static IEnumerable<float> ToFloatList(this IEnumerable<Point> vc)
        {
            return vc == null ? new float[0] : vc.SelectMany(item => item.ToArray());
        }
        public static IEnumerable<float> ToFloatList(this IEnumerable<RgbSpectrum> vc)
        {
            return vc == null ? new float[0] : vc.SelectMany(item => item.ToArray());
        }


        public static IEnumerable<float> ToFloatList(this IEnumerable<UV> vc) {
            return vc == null ? new float[0] : vc.SelectMany(item => item.ToArray());
        }

        public static IEnumerable<RgbSpectrum> ToSpectrumList(this IList<float> vc) {
            for (var i = 0; i < vc.Count; i += 3) {
                yield return new RgbSpectrum() { c1 = vc[i], c2 = vc[i + 1], c3 = vc[i + 2] };
            }
        }



        public static IEnumerable<float> ToFloatList(this IEnumerable<Normal> vc) {
            return vc == null ? new float[0] : vc.SelectMany(item => item.ToArray());
        }

        public static IEnumerable<UV> ToUVList( this FloatStore vc ) {
            var nc = vc.Count % 3 == 0 ? 3 : 2;
            for( var i = 0; i < vc.Count; i += nc ) {
                yield return new UV() { U = vc[i], V = vc[i + 1] };
            }
        }

        public static void Iterator<T>( this List<T> lst, Func<T, T> iter ) {
            lst = lst.Select(iter).ToList();
        }

        public static UV[] ToUVArray( this IEnumerable<Vector> list) {
            return list.Select(item => new UV(item.x, item.y)).ToArray();
        }

    }
}
